import json
import time

from flask import request
from flask_restful import Resource, reqparse

from shop.conf import miyao, black_ip_list
from shop.model import check_user_token
from shop.util.mylogger import MyLogger, Alogger
from shop.util.string_operation import check_hash_rigth


class My_resource(Resource):

    def __init__(self):
        self.parser = reqparse.RequestParser()
        self.error_dict = {
            "400": {  # 参数为空
                "code": 400,
                "msg": "params can not be null",
                "data": ""
            },
            "401": {  # 密钥错误
                "code": 401,
                "message": "秘钥错误",
                "data": ""
            },
            "500": {  # 黑名单错误
                "code": 500,
                "msg": "error",
                "data": ""
            },
            "402": {  # token校验失败
                "code": 402,
                "msg": "token is error",
                "data": ""
            }
        }
        self.logger = MyLogger()
        self.is_json_res = True

    def get_params(self, judge, *args, **kwargs):
        '''
        获取前端参数
        :param args:
        :return:
        '''
        # 添加参数到parser中
        for one_arg in args:
            self.parser.add_argument(one_arg)
        # 从parser中解析参数
        params = self.parser.parse_args()
        Alogger.debug("从请求中获取到的参数字典")
        Alogger.debug(params)
        Alogger.debug("=================")
        # 从新组合数据，返回一个元祖
        params_values_list = []
        for one_arg in args:
            key = one_arg
            value = params.get(key)
            # 如果前端没传参数，且有默认值，则把参数值设为默认值
            if kwargs.get(one_arg) and value is None:
                value = kwargs.get(key)
            params_values_list.append(value)

        if judge:
            # 在这里执行请求预判断
            # 判断hash和timestamp
            hash_res = self.check_hash_v2()
            if not hash_res:
                raise Exception(401)
            # 判断ip是否在黑名单内
            black_ip_res = self.check_black_ip()
            if black_ip_res:
                raise Exception(500)
        if len(params_values_list) == 1:
            return params_values_list[0]
        else:
            return tuple(params_values_list)

    def _handleRequest(self, request):
        return json.loads(request.get_data())

    def options(self):
        return {'Allow': '*'}, 200, \
               {'Access-Control-Allow-Origin': '*',
                'Access-Control-Allow-Methods': 'HEAD, OPTIONS, GET, POST, DELETE, PUT',
                'Access-Control-Allow-Headers':
                    'Content-Type, Content-Length, Authorization, Accept, X-Requested-With , yourHeaderFeild',
                }

    def check_hash(self, timestamp, hash_string):
        '''
        校验时间戳和hash
        :param timestamp:
        :param hash_string:
        :return:
        '''
        miyao_str = miyao
        if not timestamp:
            return 0
        # 首先判断时间戳和当前时间戳的差值，如果差值大于45s，就是验证失败
        now_time_stamp = time.time() * 1000
        time_difference = now_time_stamp - float(timestamp)
        if time_difference > 45 * 1000:
            return 0
        res = check_hash_rigth(miyao_str, timestamp, hash_string)
        return res

    def check_hash_v2(self):
        self.parser.add_argument("timestamp")
        self.parser.add_argument("hash_string")
        args = self.parser.parse_args()
        time_stamp = args.get("timestamp")
        hash_string = args.get("hash_string")
        hash_res = self.check_hash(time_stamp, hash_string)
        return hash_res

    def check_black_ip(self):
        user_agent = request.headers.get('User-Agent')
        ip = request.headers.get('X-Real-Ip')
        if ip in black_ip_list or \
                user_agent == "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:57.0) Gecko/20100101 Firefox/57.0":
            return True
        else:
            return False

    def check_token(self):
        '''
        检查token
        :return:
        '''
        self.parser.add_argument("token")
        args = self.parser.parse_args()
        token = args.get("token")
        user_id = check_user_token(token)
        if not user_id:
            raise Exception(402)
        return user_id

    def hasherror(self):
        return {
            "code": 401,
            "message": "秘钥错误",
            "data": ""
        }

    def blacklisterror(self):
        return {
            "code": 500,
            "msg": "error",
            "data": ""
        }

    def params_null_error(self):
        return {
            "code": 400,
            "msg": "params can not be null",
            "data": ""
        }

    def success_return(self, data=[]):
        return {
            "code": 200,
            "message": "success",
            "data": data
        }

    def error_return(self, message=None):
        if not message:
            message = "后端错误，请联系后端"
        return {
            "code": 502,
            "message": message,
            "data": ""
        }
